package com.management.department.teacherinfosystem.Service;

import com.management.department.teacherinfosystem.DTO.ActivityStatsDTO;
import com.management.department.teacherinfosystem.DTO.ActivitySubmitDTO;
import com.management.department.teacherinfosystem.Entity.Activity;
import com.management.department.teacherinfosystem.Repository.ActivityRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import jakarta.persistence.criteria.Predicate;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
public class ActivityServiceImpl implements ActivityService {

    private final ActivityRepository activityRepository;

    private String normalizeStatus(String s) {
        if (s == null || s.isBlank()) return null;
        if ("APPROVED".equalsIgnoreCase(s) || "已通过".equals(s)) return "已通过";
        if ("REJECTED".equalsIgnoreCase(s) || "已驳回".equals(s)) return "已驳回";
        if ("PENDING".equalsIgnoreCase(s) || "审核中".equals(s)) return "审核中";
        return s;
    }

    @Override
    public Page<Activity> listMyActivities(Long userId, Pageable pageable, String type, String role, String organizerLevel, String startDate, String endDate, String status) {
        String ns = normalizeStatus(status);
        Specification<Activity> spec = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            predicates.add(cb.equal(root.get("user").get("id"), userId));
            if (type != null && !type.isEmpty()) predicates.add(cb.equal(root.get("activityType"), type));
            if (role != null && !role.isEmpty()) predicates.add(cb.equal(root.get("participantRole"), role));
            if (organizerLevel != null && !organizerLevel.isEmpty()) predicates.add(cb.equal(root.get("organizerLevel"), organizerLevel));
            if (startDate != null && !startDate.isEmpty()) predicates.add(cb.greaterThanOrEqualTo(root.get("startDate"), LocalDate.parse(startDate)));
            if (endDate != null && !endDate.isEmpty()) predicates.add(cb.lessThanOrEqualTo(root.get("endDate"), LocalDate.parse(endDate)));
            if (ns != null) predicates.add(cb.equal(root.get("status"), ns));
            return cb.and(predicates.toArray(new Predicate[0]));
        };
        return activityRepository.findAll(spec, pageable);
    }

    @Override
    public Page<Activity> listAllActivities(Pageable pageable, String type, String role, String organizerLevel, String startDate, String endDate, String status) {
        String ns = normalizeStatus(status);
        Specification<Activity> spec = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (type != null && !type.isEmpty()) predicates.add(cb.equal(root.get("activityType"), type));
            if (role != null && !role.isEmpty()) predicates.add(cb.equal(root.get("participantRole"), role));
            if (organizerLevel != null && !organizerLevel.isEmpty()) predicates.add(cb.equal(root.get("organizerLevel"), organizerLevel));
            if (startDate != null && !startDate.isEmpty()) predicates.add(cb.greaterThanOrEqualTo(root.get("startDate"), LocalDate.parse(startDate)));
            if (endDate != null && !endDate.isEmpty()) predicates.add(cb.lessThanOrEqualTo(root.get("endDate"), LocalDate.parse(endDate)));
            if (ns != null) predicates.add(cb.equal(root.get("status"), ns));
            return cb.and(predicates.toArray(new Predicate[0]));
        };
        return activityRepository.findAll(spec, pageable);
    }

    @Override
    public Activity getById(Long id) {
        return activityRepository.findById(id).orElse(null);
    }

    @Override
    public Long create(Long userId, ActivitySubmitDTO dto) {
        Activity a = new Activity();
        a.setActivityName(dto.getActivityName());
        a.setActivityType(dto.getActivityType());
        a.setOrganizer(dto.getOrganizer());
        a.setOrganizerLevel(dto.getOrganizerLevel());
        a.setLocation(dto.getLocation());
        a.setStartDate(LocalDate.parse(dto.getStartDate()));
        a.setEndDate(LocalDate.parse(dto.getEndDate()));
        a.setParticipantName(dto.getParticipantName());
        a.setParticipantRole(dto.getParticipantRole());
        a.setHasReport(Boolean.TRUE.equals(dto.getHasReport()));
        a.setReportTitle(dto.getReportTitle());
        a.setStatus("审核中");

        com.management.department.teacherinfosystem.Entity.User u = new com.management.department.teacherinfosystem.Entity.User();
        u.setId(userId);
        a.setUser(u);

        return activityRepository.save(a).getId();
    }

    @Override
    public void update(Long id, Long userId, ActivitySubmitDTO dto) {
        Activity a = activityRepository.findById(id).orElseThrow(() -> new RuntimeException("活动不存在"));
        if (!a.getUser().getId().equals(userId)) throw new RuntimeException("无权修改该活动");
        if (dto.getActivityName() != null) a.setActivityName(dto.getActivityName());
        if (dto.getActivityType() != null) a.setActivityType(dto.getActivityType());
        if (dto.getOrganizer() != null) a.setOrganizer(dto.getOrganizer());
        if (dto.getOrganizerLevel() != null) a.setOrganizerLevel(dto.getOrganizerLevel());
        if (dto.getLocation() != null) a.setLocation(dto.getLocation());
        if (dto.getStartDate() != null) a.setStartDate(LocalDate.parse(dto.getStartDate()));
        if (dto.getEndDate() != null) a.setEndDate(LocalDate.parse(dto.getEndDate()));
        if (dto.getParticipantName() != null) a.setParticipantName(dto.getParticipantName());
        if (dto.getParticipantRole() != null) a.setParticipantRole(dto.getParticipantRole());
        if (dto.getHasReport() != null) a.setHasReport(dto.getHasReport());
        if (dto.getReportTitle() != null) a.setReportTitle(dto.getReportTitle());
        // 教职工修改后，状态回到“审核中”，清空审核信息
        a.setStatus("审核中");
        a.setReviewer(null);
        a.setReviewComment(null);
        a.setReviewTime(null);
        activityRepository.save(a);
    }

    @Override
    public void delete(Long id, Long userId) {
        Activity a = activityRepository.findById(id).orElseThrow(() -> new RuntimeException("活动不存在"));
        if (!a.getUser().getId().equals(userId)) throw new RuntimeException("无权删除该活动");
        activityRepository.delete(a);
    }

    @Override
    public void review(Long id, Long reviewerId, String status, String opinion) {
        Activity a = activityRepository.findById(id).orElseThrow(() -> new RuntimeException("活动不存在"));
        String s = normalizeStatus(status);
        if (s == null) s = "审核中";
        a.setStatus(s);
        a.setReviewComment(opinion);
        com.management.department.teacherinfosystem.Entity.User reviewer = new com.management.department.teacherinfosystem.Entity.User();
        reviewer.setId(reviewerId);
        a.setReviewer(reviewer);
        a.setReviewTime(java.time.LocalDateTime.now());
        activityRepository.save(a);
    }

    @Override
    public ActivityStatsDTO stats(String type, String role, String organizerLevel, String startDate, String endDate) {
        Specification<Activity> spec = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (type != null && !type.isEmpty()) predicates.add(cb.equal(root.get("activityType"), type));
            if (role != null && !role.isEmpty()) predicates.add(cb.equal(root.get("participantRole"), role));
            if (organizerLevel != null && !organizerLevel.isEmpty()) predicates.add(cb.equal(root.get("organizerLevel"), organizerLevel));
            if (startDate != null && !startDate.isEmpty()) predicates.add(cb.greaterThanOrEqualTo(root.get("startDate"), LocalDate.parse(startDate)));
            if (endDate != null && !endDate.isEmpty()) predicates.add(cb.lessThanOrEqualTo(root.get("endDate"), LocalDate.parse(endDate)));
            return cb.and(predicates.toArray(new Predicate[0]));
        };
        List<Activity> list = activityRepository.findAll(spec);
        long total = list.size();
        long approved = list.stream().filter(a -> "已通过".equals(a.getStatus()) || "APPROVED".equalsIgnoreCase(a.getStatus())).count();
        long rejected = list.stream().filter(a -> "已驳回".equals(a.getStatus()) || "REJECTED".equalsIgnoreCase(a.getStatus())).count();
        long pending = total - approved - rejected;
        return new ActivityStatsDTO(total, approved, rejected, pending);
    }
} 